<template>
  <div class="dashboard-wrapper">
    <div class="number-wrapper" @click="onGotoClient">
      <div class="global">
        <div class="nubmer-title">{{ $t('authHome.onlineClient') }}</div>
        <div class="number-value">{{ onlineTotal }}</div>
        <img src="@/project/authSys/assets/images/authDashboard/global.png" />
      </div>
      <div class="dot1x-wireless">
        <div class="nubmer-title">{{ $t('authHome.dot1xWireless') }}</div>
        <div class="number-value">{{ onlineClient.dot1xWireless }}</div>
        <img
          src="@/project/authSys/assets/images/authDashboard/dot1xWireless.png"
        />
      </div>
      <div class="dot1x-wired">
        <div class="nubmer-title">{{ $t('authHome.dot1xWired') }}</div>
        <div class="number-value">{{ onlineClient.dot1xWired }}</div>
        <img
          src="@/project/authSys/assets/images/authDashboard/dot1xWired.png"
        />
      </div>
      <div class="portal">
        <div class="nubmer-title">{{ $t('authHome.portal') }}</div>
        <div class="number-value">{{ onlineClient.portal }}</div>
        <img src="@/project/authSys/assets/images/authDashboard/portal.png" />
      </div>
      <div class="mab">
        <div class="nubmer-title">MAB</div>
        <div class="number-value">{{ onlineClient.mab }}</div>
        <img src="@/project/authSys/assets/images/authDashboard/mab.png" />
      </div>
    </div>
    <LayoutPanel>
      <div slot="title" class="title">
        <span>{{ $t('authHome.statistic') }}</span>
        <a-select
          v-model="statTimeType"
          style="width: 200px"
          @change="onChangeStatTime"
        >
          <a-select-option value="today">
            {{ $t('common.today') }}
          </a-select-option>
          <a-select-option value="yesterday">
            {{ $t('common.yesterday') }}
          </a-select-option>
          <a-select-option value="last7Days">
            {{ $t('common.last7Day') }}
          </a-select-option>
          <a-select-option value="last30Days">
            {{ $t('common.last30Day') }}
          </a-select-option>
        </a-select>
      </div>
      <div class="chart-wrapper">
        <LayoutPanel>
          <div slot="title" class="title">
            <span>{{ this.$t('localAccount.authType') }}</span>
          </div>
          <div class="chart-content">
            <div class="chart-center">
              <div class="value">{{ this.onlineStatTotal }}</div>
              <div class="title">{{ this.$t('authHome.client') }}</div>
            </div>
            <div
              ref="authTypeChartRef"
              style="width: 400px; height: 260px"
            ></div>
            <div class="blank-wrapper"></div>
          </div>
        </LayoutPanel>
        <LayoutPanel>
          <div slot="title" class="title">
            <span>{{ $t('authHome.top10Nas') }}</span>
          </div>
          <div class="chart-content">
            <div class="chart-center right">
              <div class="value">{{ this.onlineStatTotal }}</div>
              <div class="title">{{ this.$t('authHome.client') }}</div>
            </div>
            <div ref="topNasChartRef" style="width: 400px; height: 260px"></div>
            <div class="blank-wrapper"></div>
          </div>
        </LayoutPanel>
      </div>
    </LayoutPanel>

    <LayoutPanel :title="null">
      <div class="chart-wrapper">
        <LayoutPanel class="title-pannel">
          <div slot="title" class="title">
            <span>{{ $t('authHome.count') }}</span>
          </div>
          <div ref="authCountChartRef" style="height: 280px"></div>
        </LayoutPanel>
        <LayoutPanel class="title-pannel">
          <div slot="title" class="title">
            <div class="title-content">
              <span>{{ $t('authHome.clientCount') }}</span>
              <a-tooltip
                placement="top"
                :title="$t('authHome.clientCountTip')"
                arrow-point-at-center
              >
                <icon-font type="ic-help" class="ic-help-tip" />
              </a-tooltip>
            </div>
          </div>
          <div ref="authClientChartRef" style="height: 280px"></div>
        </LayoutPanel>
      </div>
    </LayoutPanel>
  </div>
</template>

<script>
import LayoutPanel from '@views/common/deviceDetail/components/components/layoutPanel.vue';
import * as echarts from 'echarts';
import lodash from 'lodash';
import authSysMixin from '@project/authSys/mixin/authSysMixin';
import { requestHttp, maccApi } from '@utils/index';
import { authTypes } from '@project/authSys/views/authClient/authTypes';
import moment from 'moment-timezone';
export default {
  name: 'authDashboard',
  mixins: [authSysMixin],
  components: {
    LayoutPanel,
  },
  data() {
    return {
      authTypes,
      onlineClient: {
        portal: 0,
        dot1xWired: 0,
        dot1xWireless: 0,
        mab: 0,
      },
      statTimeType: 'today',
      requestTimeType: 'hour', // 统计类型，hour、day
      statStartTime: '',
      statEndTime: '',

      onlineStat: {
        online: 0,
        offline: 0,
      },
      authTypeDatas: [],
      authTypeDataMap: {},
      topNasDatas: [],
      topNasMap: {},
      authCountData: {
        xDatas: [],
        yDatas: [],
      },
      authClientData: {
        xDatas: [],
        yDatas: [],
      },
    };
  },
  computed: {
    authTypeMap() {
      const tempMap = {};
      this.authTypes.forEach((item) => {
        tempMap[item.value] = item.text;
      });
      return tempMap;
    },
    onlineTotal() {
      let total = 0;
      for (let key in this.onlineClient) {
        total += this.onlineClient[key];
      }
      return total;
    },
    onlineStatTotal() {
      let total = 0;
      for (const authTypeCount of this.authTypeDatas) {
        total += authTypeCount.value;
      }
      return total;
    },
  },
  mounted() {
    this.getLicenseInfo();

    this.topNasChart = echarts.init(this.$refs.topNasChartRef);
    this.authTypeChart = echarts.init(this.$refs.authTypeChartRef);
    this.authCountChart = echarts.init(this.$refs.authCountChartRef);
    this.authClientChart = echarts.init(this.$refs.authClientChartRef);

    this.onChangeStatTime();
    this.getOnlineClient();

    window.addEventListener('resize', this.resizeChat);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChat);
  },
  methods: {
    // 获取密码相关建议
    async getLicenseInfo() {
      const res = await requestHttp({
        api: maccApi.LICENSE_INFO_GET_API,
        method: 'GET',
      });
      if (res.code === 0) {
        // tommy 240821 未激活才要做处理
        if (!res.data.activated) {
          this.$EventBus.$emit('OPEN_LIC_INFO_MODAL', {
            inExperience: res?.data?.inExperience,
            desc: res.data.desc,
          });

          // tommy 240821 不在体验下跳转license
          if (res?.data?.inExperience === false) {
            this.$router.push('sysSetting_licenseMng_menu');
          }
        }
      }
    },
    onChangeStatTime() {
      this.changeStatTimeType();
      this.getOnlinesStat();
      this.getTopNasStat();
      this.getAuthCountStat();
      this.getAuthClientStat();
    },
    changeStatTimeType() {
      const today = moment();
      let endTime = today.endOf('day').valueOf();
      let startTime = '';
      let tempDay = null;
      switch (this.statTimeType) {
        case 'yesterday':
          this.requestTimeType = 'hour';
          tempDay = today.subtract(1, 'days');
          startTime = tempDay.startOf('day').valueOf();
          endTime = tempDay.endOf('day').valueOf();
          break;
        case 'last7Days':
          this.requestTimeType = 'day';
          tempDay = today.subtract(7, 'days');
          startTime = tempDay.startOf('day').valueOf();
          break;
        case 'last30Days':
          this.requestTimeType = 'day';
          tempDay = today.subtract(30, 'days');
          startTime = tempDay.startOf('day').valueOf();
          break;
        case 'today':
        default:
          this.requestTimeType = 'hour';
          startTime = today.startOf('day').valueOf();
      }
      this.statStartTime = startTime;
      this.statEndTime = endTime;
    },

    dealStatData(queryResult) {
      switch (this.statTimeType) {
        case 'last7Days':
          return this.dealDayStatData(queryResult, 7);
        case 'last30Days':
          return this.dealDayStatData(queryResult, 30);
        case 'yesterday':
        case 'today':
        default:
          return this.dealHourStatData(queryResult);
      }
    },

    dealDayStatData(queryResult, dayNum) {
      const statData = {
        xDatas: [],
        yDatas: [],
      };
      let tempDate = moment();
      for (let i = 0; i < dayNum; i++) {
        statData.xDatas.push(tempDate.format('MM-DD'));
        tempDate = tempDate.subtract(1, 'days');
      }
      statData.xDatas = statData.xDatas.reverse();
      for (let i = 0; i < dayNum; i++) {
        statData.yDatas.push(0);
      }
      const tempMap = {};
      queryResult.forEach((item) => {
        const date = moment(item.loginTime).format('MM-DD');
        tempMap[date] = item.count;
      });
      statData.yDatas.forEach((item, index) => {
        const dataStr = statData.xDatas[index];
        if (tempMap[dataStr]) {
          statData.yDatas[index] = tempMap[dataStr];
        }
      });
      return statData;
    },

    dealHourStatData(queryResult) {
      const statData = {
        xDatas: [],
        yDatas: [],
      };
      for (let i = 0; i <= 23; i++) {
        statData.xDatas.push(i);
      }
      // for (let i = 0; i <= 23; i++) {
      //   statData.yDatas.push(0);
      // }
      queryResult.forEach((item) => {
        const hour = moment(item.loginTime).format('HH');
        statData.yDatas[parseInt(hour)] = item.count;
      });
      return statData;
    },
    async getTopNasStat() {
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_TOP_NAS_POST_API,
        method: 'POST',
        params: {
          groupId: this.groupId,
          startTime: this.statStartTime,
          endTime: this.statEndTime,
        },
      });

      if (res.data.success) {
        this.topNasDatas = [];
        this.topNasMap = {};
        if (res.data.result) {
          res.data.result.forEach((item) => {
            this.topNasDatas.push({
              name: item.deviceName,
              value: item.count,
            });
            this.topNasMap[item.deviceName] = item.count;
          });
        }
        this.updateTopNasOption();
      } else {
        this.$message.warning(res.data.message);
      }
    },
    async getAuthClientStat() {
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_AUTH_CLIENT_POST_API,
        method: 'POST',
        params: {
          groupId: this.groupId,
          type: this.requestTimeType,
          startTime: this.statStartTime,
          endTime: this.statEndTime,
        },
      });

      if (res.data.success) {
        const result = res?.data?.result || [];
        this.authClientData = this.dealStatData(result);
        this.updateClientOption();
      } else {
        this.$message.warning(res.data.message);
      }
    },
    async getAuthCountStat() {
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_AUTH_COUNT_POST_API,
        method: 'POST',
        params: {
          groupId: this.groupId,
          type: this.requestTimeType,
          startTime: this.statStartTime,
          endTime: this.statEndTime,
        },
      });

      if (res.data.success) {
        const result = res?.data?.result || [];
        this.authCountData = this.dealStatData(result);
        this.updateCountOption();
      } else {
        this.$message.warning(res.data.message);
      }
    },
    async getOnlinesStat() {
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_AUTH_TYPE_POST_API,
        method: 'POST',
        params: {
          groupId: this.groupId,
          startTime: this.statStartTime,
          endTime: this.statEndTime,
        },
      });

      if (res.data.success) {
        this.authTypeDatas = [];
        let otherTypeNum = -1;
        let mabNum = -1;
        if (res.data.result) {
          this.authTypeDataMap = {};
          res.data.result.forEach((item) => {
            if (this.getAuthTypeTxt(item.authType)) {
              // tommy 240713 整合MAB有线、无线数据
              if (['23', '24'].includes(item.authType)) {
                if (mabNum === -1) {
                  mabNum = 0;
                }
                mabNum += item.count;
              } else {
                this.authTypeDatas.push({
                  value: item.count,
                  name: this.getAuthTypeTxt(item.authType),
                });
              }
              this.authTypeDataMap[this.getAuthTypeTxt(item.authType)] =
                item.count;
            } else {
              if (otherTypeNum === -1) {
                otherTypeNum = 0;
              }
              otherTypeNum += item.count;
            }
          });
        }

        if (mabNum >= 0) {
          this.authTypeDatas.push({
            value: mabNum,
            name: 'MAB',
          });
          this.authTypeDataMap['MAB'] = mabNum;
        }

        if (otherTypeNum >= 0) {
          this.authTypeDatas.push({
            value: otherTypeNum,
            name: this.$t('common.other'),
          });
          this.authTypeDataMap[this.$t('common.other')] = otherTypeNum;
        }

        this.updateAuthTypeOption();
      } else {
        this.$message.warning(res.data.message);
      }
    },
    getAuthTypeTxt(value, record) {
      return this.authTypeMap[value]; // 显示具体的portal方式，sms，一键认证这些
    },
    async getOnlineClient() {
      const res = await this.requestHttpAuth({
        api: maccApi.MACC_ONLINE_CLIENT_GET_API,
        method: 'GET',
        querys: {
          groupId: this.groupId,
        },
      });
      if (res.data.success) {
        const result = res.data.result || [];
        result.forEach((item) => {
          switch (item.type) {
            case 2:
              this.onlineClient.dot1xWired = item.count;
              break;
            case 3:
              this.onlineClient.dot1xWireless = item.count;
              break;
            case 4:
              this.onlineClient.mab = item.count;
              break;
            case 1:
            default:
              this.onlineClient.portal = item.count;
              break;
          }
        });
      } else {
        this.$message.warning(res.data.message);
      }
    },
    resizeChat: lodash.debounce(function () {
      this.topNasChart && this.topNasChart.resize();
      this.authTypeChart && this.authTypeChart.resize();
      this.authCountChart && this.authCountChart.resize();
      this.authClientChart && this.authClientChart.resize();
    }, 300),

    /**
     * @description: 认证NAS饼状图
     * @return {*}
     */
    updateTopNasOption() {
      const topNasMap = this.topNasMap;
      const option = {
        tooltip: {
          trigger: 'item',
          textStyle: {
            align: 'left',
            // color: 'rgba(255,255,255,1)',
          },
        },
        legend: {
          textStyle: {
            fontSize: 12,
          },
          icon: 'circle',
          top: 'center',
          right: 0,
          type: 'scroll',
          orient: 'vertical',
          itemGap: 20,
          itemHeight: 8,
          formatter: function (name) {
            return `${name}: ${topNasMap[name] || 0}`;
          },
        },
        series: [
          {
            name: this.$t('authHome.client'),
            type: 'pie',
            cursor: 'default', // 更改为手型指针
            radius: ['58%', '70%'],
            center: ['32%', '50%'],
            avoidLabelOverlap: false,
            itemStyle: {
              borderColor: '#fff',
              borderWidth: 2,
            },
            labelLine: {
              show: false,
            },
            data: this.topNasDatas,
            color: [
              '#3BA1FF',
              '#36CBCB',
              '#4ECB74',
              '#FBD437',
              '#FFA940',
              '#FF85C0',
              '#F2647B',
              '#975FE5',
              '#5354CF',
              '#435188',
              '#D4D7E2',
            ],
            label: {
              // 配置标签样式
              show: false,
            },
          },
        ],
      };
      this.topNasChart.setOption(option);
    },

    /**
     * @description: 认证类型饼状图
     * @return {*}
     */
    updateAuthTypeOption() {
      const authTypeDataMap = this.authTypeDataMap;
      const option = {
        tooltip: {
          trigger: 'item',
          textStyle: {
            align: 'left',
            // color: 'rgba(255,255,255,1)',
          },
        },
        legend: {
          textStyle: {
            fontSize: 12,
          },
          icon: 'circle',
          top: 'center',
          right: 0,
          type: 'scroll',
          orient: 'vertical',
          itemGap: 20,
          itemHeight: 8,
          formatter: function (name) {
            return `${name}: ${authTypeDataMap[name] || 0}`;
          },
        },
        series: [
          {
            name: this.$t('localAccount.authType'),
            type: 'pie',
            cursor: 'default', // 更改为手型指针
            radius: ['58%', '70%'],
            center: ['32%', '50%'],
            avoidLabelOverlap: false,
            itemStyle: {
              borderColor: '#fff',
              borderWidth: 2,
            },
            label: {
              show: false,
              position: 'center',
            },
            labelLine: {
              show: false,
            },
            data: this.authTypeDatas,
            color: [
              '#3BA1FF',
              '#36CBCB',
              '#4ECB74',
              '#FBD437',
              '#FFA940',
              '#FF85C0',
              '#F2647B',
              '#975FE5',
              '#5354CF',
              '#435188',
              '#D4D7E2',
            ],
          },
        ],
      };
      this.authTypeChart.setOption(option);
    },

    updateCountOption() {
      const self = this;
      const option = {
        grid: {
          top: 36,
          bottom: 24,
          right: 16,
        },
        xAxis: {
          type: 'category',
          data: this.authCountData.xDatas,
        },
        yAxis: {
          type: 'value',
          splitLine: {
            lineStyle: {
              type: 'dashed',
            },
          },
        },
        series: [
          {
            name: this.$t('authHome.count'),
            data: this.authCountData.yDatas,
            type: 'bar',
            cursor: 'default', // 更改为手型指针
            barWidth: 10,
          },
        ],
        tooltip: {
          trigger: 'item',
          textStyle: {
            align: 'left',
            // color: 'rgba(255,255,255,1)',
          },
          formatter: function (param) {
            let res = '';
            let resTop = '';
            resTop = '<span>' + param.seriesName + '</span><br/>';
            res = `
                ${self.getToolTip(param.name)}
                <span style="font-weight:500; margin-left: 16px;">
                  ${param.value}
                </span>
              `;
            return resTop + res;
          },
        },
        color: ['#3BA1FF'],
      };
      this.authCountChart.setOption(option);
    },

    getToolTip(xAxisName) {
      if (!xAxisName.includes('-')) {
        const num = parseInt(xAxisName);
        return this.$t('authHome.hourRange', [`${num}:00`, `${num + 1}:00`]);
      } else {
        return xAxisName;
      }
    },

    updateClientOption() {
      const self = this;
      const option = {
        grid: {
          top: 36,
          bottom: 24,
          right: 16,
        },
        xAxis: {
          type: 'category',
          data: this.authClientData.xDatas,
        },
        yAxis: {
          type: 'value',
          splitLine: {
            lineStyle: {
              type: 'dashed',
            },
          },
        },
        series: [
          {
            name: this.$t('authHome.clientCount'),
            data: this.authClientData.yDatas,
            type: 'line',
            cursor: 'default', // 更改为手型指针
            symbolSize: 0,
          },
        ],
        tooltip: {
          trigger: 'axis',
          textStyle: {
            align: 'left',
            // color: 'rgba(255,255,255,1)',
          },
          // backgroundColor: 'rgba(0,0,0,0.5)', //设置背景图片 rgba格式
          // borderWidth: 0,
          // padding: 5,
          formatter: function (params) {
            let res = '';
            let resTop = '';
            for (let i = 0; i < params.length; i++) {
              resTop = `<span>${self.$t('authHome.onlinePeak')}</span><br/>`;
              res = `
                ${self.getToolTip(params[i].axisValue)}
                <span style="font-weight:500; margin-left: 16px;">
                  ${params[i].data}
                </span>
              `;
            }
            return resTop + res;
          },
          // axisPointer: {
          //   type: 'cross',
          //   animation: false,
          //   label: {
          //     backgroundColor: '#505765',
          //   },
          // },
        },
        color: ['#3BA1FF'],
      };
      this.authClientChart.setOption(option);
    },

    onGotoClient() {
      this.$router.push('authMonitor_portalAuthClient_menu');
    },
  },
};
</script>

<style lang="less" scoped>
.title-pannel {
  /deep/.layout-panel-head {
    display: flex;
  }
}
.title-content {
  display: flex;
  gap: 8px;
  align-items: center;
  i {
    font-size: 16px;
  }
}
.chart-center {
  position: relative;
  left: 170px;
  top: 103px;
  width: 80px;
  text-align: center;
  .value {
    font-size: 24px;
    line-height: 30px;
    font-weight: 500;
    color: #262626; //文字颜色
  }
  .title {
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    color: #666666; //文字颜色
  }
}
/deep/.ant-select-selection-selected-value {
  font-weight: 400;
}
.chart-content {
  display: flex;
  justify-content: center;
  .blank-wrapper {
    width: 100px;
  }
}
/deep/.mainContent {
  background: #f0f3f6;
}
/deep/.layout-panel {
  margin: 0;
}
.chart-wrapper {
  display: flex;
  gap: 16px;
  > div {
    flex: 1;
    background: #fff;
  }
  /deep/.layout-panel {
    padding: 16px;

    + .layout-panel {
      margin-top: 0;
    }
  }
  /deep/.layout-panel-head::before {
    content: '';
    width: 8px !important;
    height: 8px !important;
    border: 2px solid #80a6fe;
    background: #fff !important;
    transform: rotate(45deg);
    margin-right: 8px;
  }
}
.dashboard-wrapper {
  background: #f0f3f6;
  min-width: 1248px;
}
.number-wrapper {
  height: 100px;
  display: flex;
  gap: 16px;
  margin-bottom: 16px;
  > div {
    transition: all 0.3s ease-in;
    // &:hover {
    //   transform: scale(1.03);
    // }
    cursor: pointer;
    flex: 1;
    border-radius: 12px;
    position: relative;
    display: flex;
    align-items: center;
    flex-direction: column;
    color: white;
    align-items: flex-start;
    justify-content: center;
    padding-left: 16px;
    gap: 4px;
  }
  .number-title {
    font-weight: 500;
    line-height: 20px;
  }
  .number-value {
    font-weight: 600;
    font-size: 24px;
    line-height: 30px;
  }
  .global {
    flex: 2;
    background: #2b6afd;
    .number-title {
      line-height: 24px;
    }
    .number-value {
      font-size: 28px;
      line-height: 34px;
    }
    img {
      width: 84px;
      position: absolute;
      right: 16px;
      top: 16px;
    }
  }
  .dot1x-wireless {
    background: linear-gradient(180deg, #66baf7 0%, #4cb2fc 100%);
    img {
      width: 70px;
      position: absolute;
      right: 16px;
      bottom: 12px;
    }
  }
  .dot1x-wired {
    background: linear-gradient(133.32deg, #1dc4ba 13.52%, #2bb6ad 112.09%);
    img {
      width: 95px;
      position: absolute;
      right: 16px;
      bottom: 12px;
    }
  }
  .portal {
    background: linear-gradient(180deg, #7ea5f2 0%, #719cf3 100%);
    img {
      width: 65px;
      position: absolute;
      right: 16px;
      bottom: 12px;
    }
  }
  .mab {
    background: linear-gradient(180deg, #6dc15f 0%, #65b058 100%);
    img {
      width: 88px;
      position: absolute;
      right: 16px;
      bottom: 12px;
    }
  }
}
</style>
